#include "Rodeur.h"
#include <iostream>
//#include "lib.h"
using namespace std;

const unsigned int Rodeur::nbr_comp = 16;

const unsigned int Rodeur::nbr_restric = 5;

ListComp Rodeur::Comp[16] = {
  {"Combat ambidextre", 5, false},
  {"Déplacement silencieux", 5, false},
  {"Détecter les bruits", 10, false},
  {"Empathie animale", 10, false},
  {"Ennemi juré",  10, false},
  {"Grimper", 10, false},
  {"Langage des animaux", 5, false},
  {"Neutralisation", 10, false},
  {"Passage sans trace", 10, false},
  {"Pistage", 5, false},
  {"Se cacher dans l'ombre", 5, false},
  {"Sorts cléricaux", 10, false},
  {"Spécialisation", 10, false},
  {"Suivants", 10, false},
  {"Talent pour les arcs", 5, false},
  {"Trouver et désamorcer les pièges", 10, false}
};

ListComp Rodeur::Restric[5] = {
  {"Limitation d'armes", 5},
  {"Limitation à la maille", 5},
  {"Limitation au cuir clouté", 10},
  {"Sans armure", 15},
  {"Restriction d'utilisation d'objets magiques", 0}
};

Rodeur::Rodeur(unsigned int xp, unsigned int trait[7], unsigned int& PP)
  : Classe(xp, trait, Combattants)
{
  Type_classe = "Rodeur";
  PP += 60;
  dout(BLANK) << setfill('*') << setw(56) << '*' << endreq;
  dout(BLANK) << "Création d'un rôdeur" << endl << endreq;
  unsigned int nbr(0);
 
  for (unsigned int i(0); i<nbr_restric; i++)
    {
      if (Restric[i].Cout != 0)
	dout(BLANK) << i+1 << ' ' << Restric[i].Comp << " ("
		    << Restric[i].Cout << " pp)" << endreq;
      else
	dout(BLANK) << i+1 << ' ' << Restric[i].Comp << " (cout variable)"
		    << endreq;	
    }
  dout(BLANK) << nbr_restric+1 << " Aucune" << endreq;
  dout(BLANK) << "Choisir les restrictions" << endreq;
  
  bool test(true), deja_pris, encore(false);
  unsigned int save_PP(PP);

  do
    {
      do
	{
	  nbr = demander_unsigned_borne("Choisir les restrictions ", 1,
					nbr_restric + 1);
	  if (nbr!=nbr_restric+1)
	    {
	      if (Restric[nbr-1].Cout == 0)
		{
		  deja_pris = safe_push_back(&Comp_classe, 15+nbr);
		  if (deja_pris)
		    dout(WARN) << "Déjà sélectionné" << endreq;
		  else
		    {
		      Comp_classe.push_back(15+nbr);
		      unsigned int pps;
		      pps =  demander_unsigned("Entrez les PP obtenus : ");
		      PP += pps;
		      dout(BLANK) << "Restriction choisie : "
				  << Restric[nbr-1].Comp << endreq;
		    }
		}
	      else
		{
		  deja_pris = safe_push_back(&Comp_classe, 15+nbr);
		  if (deja_pris)
		    dout(WARN) << "Déjà sélectionné" << endreq;
		  else
		    {
		      Comp_classe.push_back(15+nbr);
		      PP += Restric[nbr-1].Cout;
		      dout(BLANK) << "Restriction choisie : "
				  << Restric[nbr-1].Comp << endreq;
		    }
		}
	    }
	  else
	    test = false;
	}
      while(test);

      affiche_competences();
      dout(BLANK) << endl <<  "1 pour continuer, 2 pour recommencer" << endreq;
      nbr = demander_unsigned_borne("Choix ", 1, 2);
      if (nbr == 2)
	{
	  PP = save_PP;
	  Comp_classe.clear();
	  test = true;
	  encore = true;
	  dout(BLANK) << endreq;
	}
      else
	encore = false;
    }
  while(encore);

  test = true;

  dout(BLANK) << "Tu as " << PP << " pp à dépenser" << endreq;
  save_PP = PP;

  for (unsigned int i(0); i<nbr_comp; i++)
    {
      if (Comp[i].Cout != 0)
	dout(BLANK) << i+1 << ' ' << Comp[i].Comp << " (" << Comp[i].Cout
		    << " pp)" << endreq;
      else
	dout(BLANK) << i+1 << ' ' << Comp[i].Comp << " (cout variable)"
		    << endreq;	
    }
  dout(BLANK) << nbr_comp+1 << " Aucune" << endreq;
  dout(BLANK) << "Choisir les compétences de classe" << endreq;

  do
    {
      do
	{
	  nbr = demander_unsigned_borne("("+write_int(PP)+" restants) ", 1,
					nbr_comp + 1);
	  if (nbr!=nbr_comp+1)
	    {
	      if (PP >= Comp[nbr-1].Cout)
		{
		  deja_pris = safe_push_back(&Comp_classe, nbr - 1);
		  if (deja_pris)
		    dout(WARN) << "Déjà sélectionné" << endreq;
		  else
		    {
		      Comp_classe.push_back(nbr-1);
		      PP -= Comp[nbr-1].Cout;
		      dout(BLANK) << "Compétence choisie : " << Comp[nbr-1].Comp
				  << endreq;
		    }
		}
	      else
		dout(BLANK) << "Pas assez de pp" << endreq;
	    }
	  else
	    test = false;
	}
      while(test);

      affiche_competences();
      dout(BLANK) << endl <<  "1 pour continuer, 2 pour recommencer" << endreq;
      nbr = demander_unsigned_borne("Choix ", 1, 2);
      if (nbr == 2)
	{
	  PP = save_PP;
	  while(Comp_classe.back() < nbr_comp)
	    Comp_classe.pop_back();
	  test = true;
	  encore = true;
	  dout(BLANK) << endreq;
	}
      else
	encore = false;
    }
  while(encore);

  dout(BLANK) << endl << setfill('*') << setw(56) << '*' << endreq;
  calcul_niveau();
  calcul_niv_mag();
}

Rodeur::Rodeur(unsigned int xp, unsigned int trait[7])
  : Classe(xp, trait, Combattants)
{
  Type_classe = "Rodeur";
  calcul_niveau();
  calcul_niv_mag();
}

Rodeur::~Rodeur()
{}

void Rodeur::calcul_niveau()
{
  if (XP < 75000)
    {
      unsigned int i;
      for (i = 0; i < 5; i++)
	{
	  if (XP < (unsigned int) 2250 * puissance(2, i))
	    break;
	}
      Niveau = i + 1;
    }
  else if (XP < 150000)
    Niveau = 7;
  else if (XP < 300000)
    Niveau = 8;
  else
      Niveau = (XP - 300000) / 300000 + 9;
}

void Rodeur::afficher_stats()
{
  dout(BLANK) << "Rodeur" << endreq;
  dout(BLANK) << "Niveau " << Niveau << ", niveau de magie " << Niveau_mag << endreq;
  for (unsigned int i(0); i < 6; i++)
    dout(BLANK) << Caracteristiques[i] << ' ' <<Traits[i] << endreq;
  for (unsigned int i(0); i < Comp_classe.size(); i++)
    {
      if(Comp_classe[i] >= nbr_comp)
	dout(BLANK) << Restric[Comp_classe[i] - nbr_comp].Comp << endreq;
      else
	dout(BLANK) << Comp[Comp_classe[i]].Comp << endreq;
    }
}

void Rodeur::appliquer_modif(const string& type)
{}

void Rodeur::augmenter_talents(const unsigned int& bonus, const bool& lvl_up)
{}

void Rodeur::get_JS(unsigned int *tab) const
{
  *(tab + 0) = 14; // Paralysie, Poison ou Mort magique
  *(tab + 1) = 16; // Bâton, batonnet baguette
  *(tab + 2) = 15; // Pétrification ou Métamorphose
  *(tab + 3) = 17; // Souffles
  *(tab + 4) = 17; // Sorts
  
  unsigned int cat;
  if (Niveau <= 2)
    cat = 0;
  else  if (Niveau <= 4)
    cat = 1;
  else  if (Niveau <= 6)
    cat = 3;
  else  if (Niveau <= 8)
    cat = 4;
  else  if (Niveau <= 10)
    cat = 6;
  else  if (Niveau <= 12)
    cat = 7;
  else  if (Niveau <= 14)
    cat = 9;
  else  if (Niveau <= 16)
    cat = 10;
  else
    cat = 11;

  *(tab + 0) -= cat;
  *(tab + 1) -= cat;
  *(tab + 2) -= cat;
  *(tab + 3) -= cat;
  *(tab + 4) -= cat;

  if (cat == 3)
    *(tab + 3) = 13;
  else if (cat == 4)
    *(tab + 3) = 12;
  else if (cat == 4)
    *(tab + 3) = 9;
  else if (cat == 6)
    *(tab + 3) = 8;
  else if (cat == 7)
    *(tab + 3) = 5;
  else if (cat >= 10)
    *(tab + 3) = 4;
}

string Rodeur::get_competence(const unsigned int& i) const
{
  if (get_comp(i) < nbr_comp)
    return Comp[get_comp(i)].Comp;
  else
    return Restric[get_comp(i)-nbr_comp].Comp;
}

unsigned int Rodeur::calcule_TAc0() const
{
  return 21 - Niveau;
}

void Rodeur::calcul_niv_mag()
{
  if (Niveau < 8)
    Niveau_mag = 0;
  else if (Niveau < 14)
    Niveau_mag = (Niveau - 7) / 2;
  else
    Niveau_mag = 3;
}

void Rodeur::ecrire_sorts(const string& nom_fichier, const bool& ecrase) const
{
  bool a_des_sort(false);
  for (unsigned int i(0); i < get_combien(); i++)
    {
      if (get_comp(i) == 9)
	{
	  a_des_sort = true;
	  break;
	}
    }
  ofstream sortie;
  if (ecrase)
    sortie.open(nom_fichier.c_str());
  else
    sortie.open(nom_fichier.c_str(), ios::app);
  if (a_des_sort)
    {
      for (unsigned int i(1); i <= Niveau_mag; i++)
	  sortie << "\\input{Sorts_clerc/Animale_" + write_int(i) + ".inc.tex}" << endreq;
      for (unsigned int i(1); i <= Niveau_mag; i++)
	  sortie << "\\input{Sorts_clerc/Végétale_" + write_int(i) + ".inc.tex}" << endreq;
    }
  else
    sortie << "% Rodeur sans sorts" << endreq;
  sortie.close();
}

void Rodeur::nbr_sort(unsigned int sorts[], const unsigned int& taille) const
{
  DebugLevelType etat_precedent(dout.getLevel());
  dout.setLevel(fonction);
  dout(DEBUG) << "Fait rien pour le moment" << endreq;
  dout.setLevel(etat_precedent);
}
